package cassys.data.hibernate;

import cassys.data.AssessmentGroupDAO;
import cassys.data.ClassGroupDAO;
import cassys.data.DAOFactory;
import cassys.data.LectureDAO;
import cassys.data.AssessmentDAO;
import cassys.data.ModuleDAO;
import cassys.data.StudentDAO;
import cassys.data.UserDAO;
import cassys.data.UserRoleMappingDAO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Returns Hibernate-specific instances of DAOs.
 * <p/>
 * If for a particular DAO there is no additional non-CRUD functionality, we use
 * a nested static class to implement the interface in a generic way. This allows clean
 * refactoring later on, should the interface implement business data access
 * methods at some later time. Then, we would externalize the implementation into
 * its own first-level class.
 *
 */
public class HibernateDAOFactory extends DAOFactory {

    private static Log log = LogFactory.getLog(HibernateDAOFactory.class);

    private GenericHibernateDAO instantiateDAO(Class daoClass) {
        try {
            System.out.println("Instantiating DAO: " + daoClass);
            log.debug("Instantiating DAO: " + daoClass);
            return (GenericHibernateDAO) daoClass.newInstance();
        } catch (Exception ex) {
            throw new RuntimeException("Can not instantiate DAO: " + daoClass, ex);
        }
    }

    public ModuleDAO getModuleDAO() {
        return (ModuleDAO) instantiateDAO(ModuleHibernateDAO.class);
    }

    public LectureDAO getLectureDAO() {
        return (LectureDAO) instantiateDAO(LectureHibernateDAO.class);
    }

    @Override
    public AssessmentDAO getAssessmentDAO() {
        return (AssessmentDAO) instantiateDAO(AssessmentHibernateDAO.class);
    }

    @Override
    public StudentDAO getStudentDAO() {
        return (StudentDAO) instantiateDAO(StudentHibernateDAO.class);
    }

    @Override
    public AssessmentGroupDAO getAssessmentGroupDAO() {
        return (AssessmentGroupDAO) instantiateDAO(AssessmentGroupHibernateDAO.class);
    }

    @Override
    public ClassGroupDAO getClassGroupDAO() {
        return (ClassGroupDAO) instantiateDAO(ClassGroupHibernateDAO.class);
    }

    @Override
    public UserRoleMappingDAO getLoginDAO() {
        return (UserRoleMappingDAO) instantiateDAO(UserRoleMappingHibernateDAO.class);
    }

    @Override
    public UserDAO getUserDAO() {
        return (UserDAO) instantiateDAO(UserHibernateDAO.class);
    }
}
